package com.google.code.openperfmon.web;

import org.apache.log4j.Logger;

import com.google.code.openperfmon.domain.AppUser;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.interceptor.Interceptor;

@SuppressWarnings("serial")
public class SecurityInterceptor implements Interceptor {
	private static Logger logger = Logger.getLogger(SecurityInterceptor.class);
	
	public void init() {
	}

	public void destroy() {
	}

	public String intercept(ActionInvocation invocation) throws Exception {
		AppUser authUser = UserSession.authUser();
		if (authUser == null) authUser = UserSession.cookieAuth();

		if (logger.isDebugEnabled()) {
			logger.debug("Invocation: " + invocation.getAction().getClass().getName());
			logger.debug("Action: " + invocation.getProxy().getActionName());
			logger.debug("Namespace: " + invocation.getProxy().getNamespace());
			logger.debug("AuthUser = " + (authUser == null ? "null" : authUser.getLogin()));
		}
		
		invocation.getStack().set("authUser", authUser == null ? Boolean.FALSE : authUser);
		
		if (invocation.getAction().getClass().isAnnotationPresent(Anonymous.class)) {
			return invocation.invoke();
		} 

		boolean requiresAdmin = "/admin".equals(invocation.getProxy().getNamespace());
		if (authUser == null) {
			addErrorIfPossible(invocation, "Log into the system");
			return "grLogin";
		}
		else if (requiresAdmin && ! authUser.isAdmin()) {
			logger.debug("Redirecting to login");
			addErrorIfPossible(invocation, "Administrator privileges required");
			return "grLogin";
		}
		else {
			return invocation.invoke();
		}
	}

	private void addErrorIfPossible(ActionInvocation invocation, String err) {
		if (invocation.getAction() instanceof ValidationAware) {
			((ValidationAware)invocation.getAction()).addActionError(err);
		}
	}
}
